#include "stdafx.h"
#include "Logger.h"
#include "WsgiErrorStream.h"

using namespace ISAPI_Python::Win32Helpers;

PYTHON_ACCESSABLE PyObject* ErrorStream_flush(ErrorStreamObject* self, PyObject* args) {
	UNREFERENCED_PARAMETER(self);

	if(!PyArg_ParseTuple(args, ":flush")) {
		return NULL;
	}
	
	//NOOP. I don't buffer anything.

	Py_INCREF(Py_None);
	return Py_None;
}

PYTHON_ACCESSABLE PyObject* ErrorStream_write(ErrorStreamObject* self, PyObject* args){
	UNREFERENCED_PARAMETER(self);

	LPCSTR message;
	int length;

	if(!PyArg_ParseTuple(args, "s#:write", &message, &length)) {
		return NULL;
	}
	std::string msg(message, length);

	//TODO: 64k max log entry length...probably ought to see what Windows does
	// when you send that big, big log entry.

	shared_ptr<Logger> logger = Logger::GetLogger(LOG_NAME);
	logger->Error(msg);

	Py_INCREF(Py_None);
	return Py_None;
}

PYTHON_ACCESSABLE PyObject* ErrorStream_writelines(ErrorStreamObject* self, PyObject* args) {
	UNREFERENCED_PARAMETER(self);

	PyObject* sequence = NULL;
	PyObject* iterator = NULL;

	if(!PyArg_ParseTuple(args, "O:writelines", sequence)) {
		return NULL;
	}

	iterator = PyObject_GetIter(sequence);

	if(NULL == iterator) {
		PyErr_SetString(PyExc_TypeError, "Argument should be an iterable of strings.");
		return NULL;
	}

	Logger_ptr logger = Logger::GetLogger(LOG_NAME);

	PyObject* item = NULL;
	while(item = PyIter_Next(iterator)) {
		if(PyString_Check(item)) { //Ignoring bad (non-string) items.
			LPSTR msg = NULL;
			ssize_t len = 0;

			PyString_AsStringAndSize(item, &msg, &len);
			std::string message(msg, len);
			logger->Error(message);
		}
		Py_DECREF(item);
	}
	
	return NULL;
}

static void ErrorStream_dealloc(ErrorStreamObject* errorStream) {
	GILock lock;
	PyObject_Del((PyObject*)errorStream);
}

PyMethodDef ErrorStreamMethods[] = {
	{ "flush", (PyCFunction)ErrorStream_flush, METH_VARARGS, 0 },
	{ "write", (PyCFunction)ErrorStream_write, METH_VARARGS, 0 },
	{ "writelines", (PyCFunction)ErrorStream_writelines, METH_VARARGS, 0 },
	{ NULL }
};

PyTypeObject ErrorStreamType = {
	PyVarObject_HEAD_INIT(NULL, 0)
	"isapi_python.ErrorStream",		//tp_name
	sizeof(ErrorStreamObject),		//tp_basicsize
	0,								//tp_itemsize
	// methods
	(destructor)ErrorStream_dealloc, //tp_dealloc
	NULL,							//tp_print
	NULL,							//tp_getattr
	NULL,							//tp_setattr
	NULL,							//tp_compare
	NULL,							//tp_repr
	NULL,							//tp_as_number
	NULL,							//tp_as_sequence
	NULL,							//tp_as_mapping
	NULL,							//tp_hash
	NULL,							//tp_call
	NULL,							//tp_str
	NULL,							//tp_getattro
	NULL,							//tp_setattro
	NULL,							//tp_as_buffer
	Py_TPFLAGS_DEFAULT,				//tp_flags
	NULL,							//tp_doc
	NULL,							//tp_traverse
	NULL,							//tp_clear
	NULL,							//tp_richcompare
	NULL,							//tp_weaklistoffset
	NULL,							//tp_iter,
	NULL,							//tp_iternext
	ErrorStreamMethods,				//tp_methods
	NULL,							//tp_members
	NULL,							//tp_getset
	NULL,							//tp_base
	NULL,							//tp_dict
	NULL,							//tp_descr_get
	NULL,							//tp_descr_set
	NULL,							//tp_dictoffset
	NULL,							//tp_init
	NULL,							//tp_alloc
	NULL,							//tp_new
	NULL,							//tp_free
	NULL,							//tp_is_gc
};